package br.fmapn.reporter;

import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import br.fmapn.process.entities.BusinessOperation;
import br.fmapn.process.entities.BusinessProcess;
import br.fmapn.register.BusinessProcessServices;
import br.fmapn.register.BusinessProcessServicesRemote;
import br.fmapn.reporter.util.MappingEffiencienceReport;

/**
 * Session Bean implementation class BusinessProcessReporter
 */
@Stateless
public class BusinessProcessReporter implements BusinessProcessReporterRemote {

	@PersistenceContext(unitName="fmapn")
	private EntityManager entityManager;

	//@EJB
	//BusinessProcessServicesRemote businessProcessServices;

	/**
	 * Default constructor. 
	 */
	public BusinessProcessReporter() {
		// TODO Auto-generated constructor stub
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<BusinessProcess> getBusinessProcessWithCountExecutions(){
		Query query = entityManager.createNamedQuery("findAllBusinessProcess");

		List<BusinessProcess> lista = query.getResultList();

		for(BusinessProcess bp : lista){
			bp.setNumberExecutions(Integer.parseInt(getNumberOfExecutionByBusinessProcess(bp).toString()));
		}
		return lista;
	}

	@Override
	public List<BusinessOperation> getOperationsMappingEfficienceByBusinesProcess(BusinessProcess bp){
		Query query = entityManager.createNamedQuery("findBusinessOperarionByBusinessProcess");
		query.setParameter("idBP", bp.getId());
		@SuppressWarnings("unchecked")
		List<BusinessOperation> listaBO =  query.getResultList();
		for (BusinessOperation bo : listaBO) {
			bo.setMappingEffiencienceReport(getMappingEffiencienceReport(bo));
		}
		return listaBO;
	}

	private Long getNumberOfExecutionByBusinessProcess(BusinessProcess bp){
		Query query = entityManager.createQuery("Select count(*) FROM UserBusinessProcess ubp WHERE ubp.businessProcess.id = :id");
		query.setParameter("id", bp.getId());
		return (Long) query.getSingleResult();
	}

	private MappingEffiencienceReport getMappingEffiencienceReport(BusinessOperation bo){
		int mapped = Integer.parseInt(getNumberOfMappedBusinessOperation(bo).toString());
		int notMapped = Integer.parseInt(getNumberOfNotMappedBusinessOperation(bo).toString());
		int numberSessions = Integer.parseInt(getDistinctSessionExecutedOperationBusines(bo).toString());
		
		MappingEffiencienceReport mapping = new MappingEffiencienceReport();
		mapping.setNumberExecutionsMapped(mapped);
		mapping.setNumberExecutionsNotMapped(notMapped);
		mapping.setNumberOfSessions(numberSessions);

		return mapping;
	}

	

	private Long getNumberOfMappedBusinessOperation(BusinessOperation bo){
		Query query = entityManager.createQuery("Select count(*) FROM UserBusinessOperation ubo WHERE ubo.id " +
		"IN (SELECT bo.id FROM UserBusinessProcess ubp JOIN ubp.userBusinessOperation bo) AND  ubo.businessOperation.id = :id");
		query.setParameter("id", bo.getId());
		return (Long) query.getSingleResult();
	}

	private Long getNumberOfNotMappedBusinessOperation(BusinessOperation bo){
		Query query = entityManager.createQuery("Select count(*) FROM UserBusinessOperation ubo WHERE ubo.id " +
		"NOT IN (SELECT bo.id FROM UserBusinessProcess ubp JOIN ubp.userBusinessOperation bo) AND  ubo.businessOperation.id = :id");
		query.setParameter("id", bo.getId());
		return (Long) query.getSingleResult();
	}
	
	private Long getDistinctSessionExecutedOperationBusines(BusinessOperation bo) {
		Query query = entityManager.createQuery("Select count(Distinct ubo.session) FROM UserBusinessOperation ubo WHERE " +
		"ubo.businessOperation.id = :id");
		query.setParameter("id", bo.getId());
		return (Long) query.getSingleResult();
	}

}
